package rtda

import (
	"hi-jvm/rtda/heap"
)

// 栈帧存储方法的状态
// 在任一时刻，某一线程肯定在执行某个方法，这个方法叫当前方法
// 执行该方法的帧叫线程当前帧
// 声明该方法的类叫当前类
// 如果方法是Java方法，则PC寄存器存放当前正在执行的Java虚拟机指令的地址，
// 否则，当前方法是本地方法，pc寄存器中的值没有明确定义
type Frame struct {
	lower *Frame
	LocalVars LocalVars	// 保存局部变量表指针
	OperandStack *OperandStack	// 操作数栈
	Thread       *Thread	// 为实现指令跳转而添加
	Method       *heap.Method	//
	NextPC       int 	// the next instruction after the call， 为实现指令跳转而添加
}

func NewFrame(thread *Thread, method *heap.Method) *Frame {
	return &Frame{
		Thread:       thread,
		LocalVars: newLocalVars(method.MaxLocals),
		OperandStack: newOperandStack(method.MaxStack),
	}
}

func (self *Frame)GetConstantPool() *heap.ConstantPool {
	return self.Method.Class.ConstantPool
}

func (self *Frame)GetClassRef(index uint) *heap.ClassRef {
	cp := self.GetConstantPool()
	return cp.GetConstant(index).(*heap.ClassRef)
}

func (self *Frame)GetClass(index uint) *heap.Class {
	cp := self.GetConstantPool()
	classRef := cp.GetConstant(index).(*heap.ClassRef)
	return classRef.ResolvedClass()
}
func (self *Frame) GetConstant(index uint) heap.Constant {
	cp := self.GetConstantPool()
	return cp.GetConstant(index)
}

func (self *Frame) RevertNextPC() {
	self.NextPC = self.Thread.PC
}